package com.hllxd.hism.star.basic.service.collect;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;


public class OkHttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
    private final OkHttpClient okHttpClient;
    private static volatile OkHttpUtil mInstance;

    private OkHttpUtil() {
        //添加cookie
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(30000, TimeUnit.MILLISECONDS)
                .readTimeout(30000, TimeUnit.MILLISECONDS)
                .build();
    }

    /**
     * 单例模式创建OkHttpUtil
     *
     * @return mInstance
     */
    public static OkHttpUtil getInstance() {
        if (mInstance == null) {
            synchronized (OkHttpUtil.class) {
                mInstance = new OkHttpUtil();
            }
        }
        return mInstance;
    }

    public static String buildParamStr(Map<String, String> requestParams) {
        StringBuilder retStr = new StringBuilder();
        if (requestParams == null || requestParams.size() == 0) {
            return retStr.toString();
        }
        Set<Map.Entry<String, String>> entries = requestParams.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (retStr.length() != 0) {
                retStr.append('&');
            }
            retStr.append(key).append('=').append(value);
        }

        return retStr.toString();
    }

    /**
     * get 同步请求
     *
     * @return response
     */
    private Response _getDataSync(String url) {
        Request request = new Request.Builder()
                .get()//默认get,可省略
                .url(url)
                .build();
        try {
            return okHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * get 同步请求
     *
     * @return 字符串
     */
    private String _getDataString(String url) throws IOException {
        try (Response response = _getDataSync(url)) {
            if (response.body() != null) {
                return Objects.requireNonNull(response.body()).string();
            }
        }
        return null;
    }

    public String getDataStringByParam(String url, Map<String, String> params) throws IOException {
        String paramStr = buildParamStr(params);
        String finalUrl = url + "?" + paramStr;
        logger.info("request url:{}", finalUrl);
        long start = System.currentTimeMillis();
        try (Response response = _getDataSync(finalUrl)) {
            if (null != Objects.requireNonNull(response).body()) {
                ResponseBody responseBody = Objects.requireNonNull(response.body());
                String string = responseBody.string();
                logger.info("request url:{},costTime:{}ms", finalUrl, (System.currentTimeMillis() - start));
                return string;
            }
        }

        return null;
    }


//    /**
//     * get 异步请求
//     */
//    private void _getDataAsync(String url, final ResultCallback callback) {
//        final Request request = new Request.Builder()
//                .url(url)
//                .build();
//        deliveryResult(callback, request);
//    }

    /**
     * post 同步请求
     *
     * @return response
     */
    public Response _postDataSync(String url, Map<String, String> params) throws IOException {
        Request request = buildPostRequest(url, params);
        return okHttpClient.newCall(request).execute();

    }

    /**
     * post 同步请求
     *
     * @return 字符串
     */
    public String _postDataString(String url, Map<String, String> params) throws IOException {
        try (Response response = _postDataSync(url, params)) {
            return Objects.requireNonNull(response.body()).string();
        }
    }

    public String putDataString(String url, Map<String, String> params) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSONObject.toJSONString(params), mediaType);
        Request request = new Request.Builder()
                .url(url)
                .put(body)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            return Objects.requireNonNull(response.body()).string();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

//    /**
//     * post 异步请求
//     */
//    private void _postDataAsync(String url, final ResultCallback callback, Param... params) {
//        Request request = buildPostRequest(url, params);
//        deliveryResult(callback, request);
//
//    }

//    /**
//     * post 异步请求
//     */
//
//    private void _postDataAsync(String url, final ResultCallback callback, Map<String, String> params) {
//        Param[] paramsArr = map2Params(params);
//        Request request = buildPostRequest(url, paramsArr);
//        deliveryResult(callback, request);
//    }

//    /**
//     * 异步基于post的多文件上传
//     */
//    private void _postDataFileAsync(String url, final ResultCallback callback, File[] files, String[] fileKeys, Param... params) {
//        Request request = buildMultipartFormRequest(url, files, fileKeys, params);
//        deliveryResult(callback, request);
//    }

//    /**
//     * 异步基于post的文件上传，单文件不带参数上传
//     *
//     * @param url
//     * @param callback
//     * @param file
//     * @param fileKey
//     */
//    private void _postDataFileAsync(String url, ResultCallback callback, File file, String fileKey) {
//        Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, null);
//        deliveryResult(callback, request);
//    }

//    /**
//     * 异步基于post的文件上传，单文件且携带其他form参数上传
//     *
//     * @param url      接口地址
//     * @param callback callback
//     * @param file     file
//     * @param fileKey  fileKey
//     * @param params   params
//     */
//    private void _postDataFileAsync(String url, ResultCallback callback, File file, String fileKey, Param... params) {
//        Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, params);
//        deliveryResult(callback, request);
//    }

    /**
     * 同步 post上传json对象
     *
     * @param url     url;
     * @param jsonStr json 字符串
     * @return 字符串
     * @throws IOException
     */
    private String _postJsonDataSync(String url, String jsonStr) throws IOException {
        String result = null;
        MediaType JSON = MediaType.parse("text/html;charset=utf-8");
        RequestBody requestBody = RequestBody.create(JSON, jsonStr);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            result = Objects.requireNonNull(response.body()).string();
            return result;
        }
    }

//    /**
//     * get 同步请求
//     *
//     * @param url 接口地址
//     * @return response
//     */
//    public static Response getDataSync(String url) {
//        return getInstance()._getDataSync(url);
//    }

    /**
     * get 同步请求
     *
     * @param url 接口地址
     * @return 字符串
     */
    public static String getDataString(String url) throws IOException {
        return getInstance()._getDataString(url);
    }

//    /**
//     * get 异步请求
//     *
//     * @param url 接口地址
//     */
//    public static void getDataAsync(String url, final ResultCallback callback) {
//        getInstance()._getDataAsync(url, callback);
//    }

    /**
     * post 同步请求
     *
     * @param url   url
     * @param param param
     * @return response
     */
    public static Response postDataSync(String url, Map<String, String> param) throws IOException {
        return getInstance()._postDataSync(url, param);
    }

    /**
     * post 同步请求
     *
     * @param url url
     * @return 字符串
     */
    public static String postDataString(String url, Map<String, String> param) throws IOException {
        return getInstance()._postDataString(url, param);
    }

//    /**
//     * map 转换为 Param
//     *
//     * @param params map
//     * @return params
//     */
//    private Param[] map2Params(Map<String, String> params) {
//        if (params == null) {
//            return new Param[0];
//        }
//        int size = params.size();
//        Param[] res = new Param[size];
//        Set<Map.Entry<String, String>> entries = params.entrySet();
//        int i = 0;
//        for (Map.Entry<String, String> entry : entries) {
//            res[i++] = new Param(entry.getKey(), entry.getValue());
//        }
//        return res;
//    }

    /**
     * 创建 PostRequest
     *
     * @param url    url
     * @param params params
     * @return request
     */
    private Request buildPostRequest(String url, Map<String, String> params) {
        if (params == null) {
            params = new HashMap<>();
        }
        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, String>> entries = params.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            builder.add(entry.getKey(), entry.getValue());
        }

        RequestBody requestBody = builder.build();
        return new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
    }

//    public static class Param {
//        public Param() {
//        }
//
//        public Param(String key, String value) {
//            this.key = key;
//            this.value = value;
//        }
//
//        String key;
//        String value;
//    }

}
